package hatkins.display
{
	/**
	 * A view of a Patch object
	 */
	public class PatchHatkinsView extends RenderedHatkinsView
	{
		private var _patch:Patch;
		
		private var _cameraPixelX:int;
		private var _cameraPixelY:int;

		/**
		 * Creat the view
		 */
		public function PatchHatkinsView() {
			super();
			_cameraPixelX = 0;
			_cameraPixelY = 0;
		}
		
		/**
		 * @copy
		 */
		public override function render(invalidX:int, invalidY:int, invalidWidth:int, invalidHeight:int):void {
			clearRect(invalidX, invalidY, invalidWidth, invalidHeight);
			if (_patch!=null) {
				_patch.blit(renderBuffer, invalidX, invalidY, invalidX - _cameraPixelX, invalidY - _cameraPixelY, invalidWidth, invalidHeight);
			}
		}
		
		/**
		 * Get or set the patch
		 */
		public function set patch(value:Patch):void {
			_patch = value;
			renderAll();
		}
		public function get patch():Patch {
			return _patch;
		}
		
		/**
		 * @copy
		 */
		public override function placeCamera(positionX:Number, positionY:Number):void {
			super.placeCamera(positionX, positionY);
			_shiftCamera(cameraX - positionX, cameraY - positionY);
		}

		/**
		 * @copy
		 */
		public override function shiftCamera(shiftX:Number, shiftY:Number):void {
			var positionX:Number = cameraX;
			var positionY:Number = cameraY;
			super.shiftCamera(shiftX, shiftY);
			_shiftCamera(cameraX - positionX, cameraY - positionY);
		}
				
		private function _shiftCamera(offsetX:Number, offsetY:Number):void {
			
			var diffX:int = int(cameraX - _cameraPixelX);
			var diffY:int = int(cameraY - _cameraPixelY);

			if (diffX!=0) {
				_cameraPixelX = int(cameraX);
			}
			
			if (diffY!=0) {
				_cameraPixelY = int(cameraY);
			}
			
			// scroll the bitmap for a speed boost!
			if (Math.abs(diffX) < viewportWidth && Math.abs(diffY) < viewportWidth) {
				renderBuffer.scroll(diffX, diffY);
			
				if (diffY < 0) {
					// bottom strip
					render(0, viewportHeight + diffY, viewportWidth, -diffY);
					if (diffX < 0) {
						// right strip
						render(viewportWidth + diffX, 0, -diffX, viewportHeight + diffY);
					}
					else if (diffX > 0) {
						// left strip
						render(0, 0, diffX, viewportHeight + diffY);
					}
				}
				else if (diffY > 0) {
					// top strip
					render(0, 0, viewportWidth, diffY);
					if (diffX < 0) {
						// right strip
						render(viewportWidth + diffX, diffY, -diffX, viewportHeight - diffY);
					}
					else if (diffX > 0) {
						// left strip
						render(0, diffY, diffX, viewportHeight - diffY);
					}
				}
				else {
					if (diffX < 0) {
						// right strip
						render(viewportWidth + diffX, 0, -diffX, viewportHeight);
					}
					else if (diffX > 0) {
						// left strip
						render(0, 0, diffX, viewportHeight);
					}
				}
			}
			else {
				renderAll();
			}
		}
	}
}